package wolf.iu.framework;

import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeMap;

import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldInsnNode;
import org.objectweb.asm.tree.FieldNode;

import wolf.iu.framework.hooks.AbstractClassHookEnum;
import wolf.iu.framework.hooks.AbstractFieldHookEnum;

public class HooksList {
    private final TreeMap<AbstractClassHookEnum, ClassHookContainer> classMappings = new TreeMap<AbstractClassHookEnum, ClassHookContainer>();

    ClassesHandler ch;
    
    public HooksList(final ClassesHandler ch) {
        this.ch = ch;
    }
    
    public ClassHookContainer setClassHook(final AbstractClassHookEnum hook,
            final ClassContainer class_) {
        final ClassHookContainer chc = new ClassHookContainer(class_);
        this.classMappings.put(hook, chc);
        return chc;
    }

    public ClassHookContainer setClassHook(final AbstractClassHookEnum hook,
            final ClassNode class_) {
        if (classMappings.containsKey(hook))
            return classMappings.get(hook);
        return this.forceSetClassHook(hook, class_);
    }
    
    public ClassHookContainer forceSetClassHook(final AbstractClassHookEnum hook,
            final ClassNode class_) {
        if (class_ == null) {
            System.err.println(hook.getName() + " is not valid classhook");
            return null;
        }
        return this.setClassHook(hook, new ClassContainer(class_));
    }

    public ClassHookContainer setFieldHook(
            final AbstractClassHookEnum classHook,
            final AbstractFieldHookEnum fieldHook, final FieldInsnNode fin) {
        final ClassHookContainer chc = classMappings.get(classHook);
        if (chc == null)
            // TODO chc = setClassHook(classHook, ch.getClass(fin.owner));
            return null;
        chc.setFieldHook(fieldHook, fin);
        return chc;
    }

    public Set<Entry<AbstractClassHookEnum, ClassHookContainer>> getClassMappings() {
        return classMappings.entrySet();
    }

    public boolean containsHook(final AbstractClassHookEnum t) {
        return classMappings.containsKey(t);
    }

    public boolean containsHook(final String class_) {
        for (final ClassHookContainer cHook : classMappings.values()) {
            if (cHook.getFullOldName().equals(class_))
                return true;
        }
        return false;
    }

    public ClassHookContainer getHook(final String class_) {
        for (final ClassHookContainer cHook : classMappings.values()) {
            if (cHook.getFullOldName().equals(class_))
                return cHook;
        }
        return null;
    }

    public ClassHookContainer getHook(final AbstractClassHookEnum t) {
        return this.classMappings.get(t);
    }
}
